package com.qf.smsplatform.interfaces.service.impl;

import com.netflix.discovery.converters.Auto;
import com.qf.smsplatform.common.constants.CacheConstants;
import com.qf.smsplatform.common.constants.RabbitMQConstants;
import com.qf.smsplatform.common.constants.SourceConstants;
import com.qf.smsplatform.common.enums.SmsEnum;
import com.qf.smsplatform.common.exception.SmsException;
import com.qf.smsplatform.common.model.StandardSubmit;
import com.qf.smsplatform.common.util.MobileFormatUtil;
import com.qf.smsplatform.common.util.SnowFlakeUtil;
import com.qf.smsplatform.interfaces.client.CacheClient;
import com.qf.smsplatform.interfaces.dto.SmsDTO;
import com.qf.smsplatform.interfaces.service.InterfaceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 接口模块鉴权接口
 *
 * @author zjw
 */
@Service
@Slf4j
public class InterfaceServiceImpl implements InterfaceService {

    @Autowired
    private CacheClient cacheClient;

    @Autowired
    private SnowFlakeUtil snowFlakeUtil;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void checkSmsParam(SmsDTO smsDTO) {
        // ===============1. ClientID==========================
        //1.1 是否为空
        String clientID = smsDTO.getClientID();
        if (StringUtils.isEmpty(clientID)) {
            // clientID有问题
            log.info("【接口模块-下行接口】 认证错误：clientId错误  clientID = {}", clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CLIENTID);
        }
        //1.2 去缓存模块查询客户信息
        Map map = cacheClient.hGetAll(CacheConstants.CACHE_PREFIX_CLIENT + clientID);
        //1.3 判断客户信息是否空
        if (map == null || map.size() == 0) {
            // clientID有问题
            log.info("【接口模块-下行接口】 认证错误：clientId错误  clientID = {}", clientID);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_CLIENTID);
        }

        // ===============2. pwd==========================
        //2.1 为空 或者 不等于当前客户的pwd
        String pwd = smsDTO.getPwd();
        if (StringUtils.isEmpty(pwd) || !pwd.equals(map.get("pwd"))) {
            // pwd有问题
            log.info("【接口模块-下行接口】 密码错误  pwd = {}", pwd);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_PWD);
        }


        // TODO ===============3. ip==========================
        //3.1 获取当前客户的白名单ip

        //3.2 判断当前客户端真实ip是否满足白名单

        // TODO ===============4. content，文字超多100个字，也不处理，分成多条发送==========================
        String content = smsDTO.getContent();
        //4.1  短信内容非空！


        // ===============5. mobile，凉了也不抛出异常，最后统处理==========================
        String mobiles = smsDTO.getMobile();
        //5.1 手机号非空
        if (StringUtils.isEmpty(mobiles)) {
            // mobile有问题
            log.info("【接口模块-下行接口】 手机号错误，不能为空！  mobiles = {}", mobiles);
            throw new SmsException(SmsEnum.INTERFACE_PARAMETER_MOBILE_EMPTY);
        }

        String[] mobileArray = mobiles.split(",");
        Set<String> okMobile = new HashSet<>();
        Set<String> errorMobile = new HashSet<>();
        for (String mobile : mobileArray) {
            //5.2 判断手机号格式，整理手机号格式不对的
            if (MobileFormatUtil.checkMobile(mobile)) {
                // 手机号正确
                //5.3 整理出正确的前10个手机号  整理100（10）个后的手机号
                if (okMobile.size() < 10) {
                    okMobile.add(mobile);
                } else {
                    errorMobile.add(mobile);
                }
            } else {
                // 手机号错误
                errorMobile.add(mobile);
            }
        }


        // TODO ===============6. srcID==========================
        String srcID = smsDTO.getSrcID();
        //6.1 可以为null，但是必须是数值，
        // ===============7. 封装成消息，StandardSubmit ==================
        // 每一条短信对应一个消息。
        for (String mobile : okMobile) {
            // 判断短信内容是否超过100个字符
            int contentLength = content.length();
            // 超过100，分多条发送   99
            // 超过限制，需要将短息内容分为多条发送
            int count = contentLength / 100;
            if (count == 0) {
                count = 1;
            }
            if (count * 100 < contentLength) {
                count++;
            }
            // 当前一条短信需要分为几条发送
            for (int i = 0; i < count; i++) {
                StandardSubmit submit = new StandardSubmit();
                // 7.1 利用雪花算法生成全局唯一标识
                long sequenceId = snowFlakeUtil.nextId();

                // 7.2 计算短信文本
                String messageContent = null;
                if (i == count - 1) {
                    messageContent = content.substring(i * 100, contentLength);
                } else {
                    messageContent = content.substring(i * 100, (i + 1) * 100);
                }
                // 7.3 封装Submit的基本数据  sequenceId，clientID，srcSequenceId，destMobile，messageContent，source
                submit.setSequenceId(sequenceId + "");
                submit.setClientID(Integer.valueOf(clientID));
                submit.setSrcSequenceId(srcID == null ? null : Long.parseLong(srcID));
                submit.setDestMobile(mobile);
                submit.setMessageContent(messageContent);
                submit.setSource(SourceConstants.HTTP);

                // 7.4 发送到RabbitMQ的队列中
                rabbitTemplate.convertAndSend(RabbitMQConstants.TOPIC_PRE_SEND, submit);
            }
        }


        // TODO ===============8. 如果errorMobile中有手机号，返回给用户 ==============================

    }
}
